property length
property prototype,constructor,__proto__

----- Class Methods -----

on new me, a
  me.length = a
  return me
end

on CreateLingoExpression me,lstArgs,lingoCode
  repeat with i = 1 to lstArgs.count()
    argsText = argsText & lstArgs[i] &" = params["&string(i)&"]"&RETURN
  end repeat  
  scriptMember = member("scrLingoExpression(Temp)")
  m = scriptMember.membernum --> if exist is better for perfomance (double)
  if (m < 0) then scriptMember = _movie.new(#script)
  scriptMember.scriptText = "property ancestor"&RETURN&"on ApplyList me,params"&RETURN&argsText&lingoCode&RETURN&"end"  
  scriptInstance = script(scriptMember).new()
  scriptInstance.ancestor = script ("scrLambda").new(lstArgs.count())
  if (m < 0) then scriptMember.erase()
  return scriptInstance
end


----- Public Methods -----

on apply me,jobj,lsListOrJsArray
  if (listP(lsListOrJsArray)) then return me.ApplyList(lsListOrJsArray)
  lst = []
  repeat with i = 0 to lsListOrJsArray.length-1 
    lst.add(lsListOrJsArray[i])
  end repeat
  return me.ApplyList(lst)
end

on invoke me
  v = me
  repeat with i = 2 to the paramcount
    v = v[param(i)]    
  end repeat
  return v
end

on ApplyOne me,x, vars
  vnames = me.TryGetVarNames(x)
  if not (vnames.count()) then v = x
  else
    can = me.CanGetAllValues(x,vars)
    if can then
      v = x.EvalWith(vars)
    else
      c = script("scrVarClosure").new(vnames)
      c.pOuterFunction = me
      c.pInnerFunction = x
      return c
    end if
  end if
  
  if (me.length = 1) then return me.ApplyList([v])
  
  c = script("scrArgClosure").new(me.length-1)
  c.pTarget = me
  c.pContext = v
  return c
end

on Skip me
  c = script("scrSkipArgClosure").new(me.length)
  c.pTarget = me
  return c
end


----- Alias -----
-- Apply One Parameter
on GetAt me,x
  return me.ApplyOne(x)
end

-- to allow pseudo-operators combinations using shortcuts
on GetProp me,x,y
  if LingoF().handler(x) then return call(x,LingoF(),me)[y] 
  return call(x,_movie,me)[y]
end

on GetPropRef me,x,y
  if LingoF().handler(x) then return call(x,LingoF(),me)[y] 
  return call(x,_movie,me)[y]
end

--------- private ---------

on TryGetVarNames me,varClosure
  if varClosure.ilk = #LingoF_LambdaExpression then return varClosure.getUnboundedVars()
  return []
end

on CanGetAllValues me,varClosure,vars
  if voidP(vars) then return false
  repeat with varname in varClosure.getUnboundedVars()
    if not vars.getPos(varname) then return false
  end repeat
  return true
end

on TryGetValue me,varClosure,vars
  if voidP(vars) then return []
  p = vars.key.getOne(varClosure.getUnboundedVars())
  if p then return {vars.val[p]}
  return []  
end 